import os 
from multiprocessing.managers import BaseManager 
from fastapi import FastAPI, Request, UploadFile, File , Form
from fastapi.responses import JSONResponse 
from fastapi.exceptions import RequestValidationError 
from fastapi.middleware.cors import CORSMiddleware 
from pydantic import BaseModel 
from typing import List 

from multiprocessing.managers import BaseManager 
import uvicorn 

import asyncio 
import uuid
import sqlite3
from datetime import datetime

UPLOAD_DIR = "./uploaded_docs"
DB_NAME = "doc_metadata.db"
app = FastAPI() 
# 启用 CORS 
app.add_middleware( 
 CORSMiddleware, 
 allow_origins=["*"], 
 allow_methods=["*"], 
 allow_headers=["*"], 
) 
# 连接 Index Server 模块
manager = BaseManager(('localhost', 5602), b'password') 
manager.register('query_index') 
manager.register('insert_into_index')
manager.register('get_documents_list') 
manager.register('delete_from_index')
manager.connect() 
#增加一个测试接口@app.get(“/”),返回字符串“Hello World”
@app.get("/")
def hello():
    return {"message": "Hello World"}   
    


@app.post("/uploadFile/")
async def upload_file(file: UploadFile = File(...)):
    try:
        # 保存文件到上传目录
        file_name = file.filename
        dest_path = os.path.join(UPLOAD_DIR, file_name)
        
        # 处理重名文件
        counter = 1
        base_name, ext = os.path.splitext(file_name)
        while os.path.exists(dest_path):
            dest_path = os.path.join(UPLOAD_DIR, f"{base_name}_{counter}{ext}")
            counter += 1
        
        # 保存文件
        with open(dest_path, "wb") as buffer:
            content = await file.read()
            buffer.write(content)
        
        # 记录元数据
        file_size = os.path.getsize(dest_path)
        upload_time = datetime.now().isoformat()
        
        with sqlite3.connect(DB_NAME) as conn:
            conn.execute(
                "INSERT INTO documents VALUES (?, ?, ?, ?, ?)",
                (str(uuid.uuid4()), file_name, dest_path, upload_time, file_size)
            )
        
        # 调用索引服务处理文档
        manager.insert_into_index(dest_path)._getvalue()
        return JSONResponse(content={"status": "success", "path": dest_path})
    
    except Exception as e:
        return JSONResponse(content={"error": str(e)}, status_code=500)






@app.exception_handler(RequestValidationError) 
async def validation_exception_handler(request, exc): 
    return JSONResponse(content="Invalid request parameters", status_code=400)

@app.get("/query/") 
def query_index(request: Request, query_text: str): 
    global manager 
    if not query_text:
        return JSONResponse(content="请输入查询内容", status_code=400)
    
    try:
        response = manager.query_index(query_text)._getvalue()
        
        # 处理空响应
        if isinstance(response, str):  # 捕获错误信息或空结果提示
            return JSONResponse(content={"text": response}, status_code=200)
            
        response_json = { 
            "text": str(response),
            "sources": [{
                "text": str(x.text),
                "similarity": round(x.score, 2),
                "doc_id": str(x.id_) 
            } for x in response.source_nodes]
        }
        return JSONResponse(content=response_json, status_code=200)
    except Exception as e:
        return JSONResponse(
            content={"error": f"查询处理失败: {str(e)}"},
            status_code=500
        )




@app.get("/getDocuments") 
def get_documents(request: Request): 
    document_list = manager.get_documents_list()._getvalue()
    # 转换时间格式
    for doc in document_list:
        doc["upload_time"] = datetime.fromisoformat(doc["upload_time"]).strftime("%Y-%m-%d %H:%M")
    return JSONResponse(content=document_list, status_code=200)
@app.delete("/deleteDocument/{doc_id}")
def delete_document(doc_id: str):
    #打印
    print(f"接收前端doc_id: {doc_id}")
    try:
        success = manager.delete_from_index(doc_id)._getvalue()
        if success:
            return JSONResponse(
                content={"success": True, "message": "文档删除成功"},
                status_code=200
            )
        else:
            return JSONResponse(
                content={"success": False, "message": "文档不存在或删除失败"},
                status_code=404
            )
    except Exception as e:
        # 新增详细错误日志
        print(f"删除操作异常: {str(e)}")
        return JSONResponse(
            content={"success": False, "message": f"服务器错误: {str(e)}"},
            status_code=500
        )




if __name__ == "__main__":
     uvicorn.run(app, host="localhost", port=5601)